#pragma once
#include <string>
#include <qtreewidget.h>
#include <LitExceptions.h>
#include <LitFileSystem.h>
#include <LitCore.h>
#include "ProjectItem.h"
#include "ProjectItemProperties.h"
#include "ProjectCreatorDialog.h"
#include "ProjectSaveState.h"
#include "UserSceneQuery.h"

#define EDITOR_BASE_PATH (Lit::FileSystem::applicationPath()+"/")
#define EDITOR_PATH (EDITOR_BASE_PATH+std::string("editor/"))
#define EDITOR_DEFAULT_PROJECT_PATH (EDITOR_PATH+std::string("UserProjects/"))

#define QT_RESOURCES_PATH QString(":/Resources/")
#define QT_ITEM_TYPES_PATH QString(QT_RESOURCES_PATH+"ItemTypes/")
/*
void Project::saveProject( const std::string &as ){
	std::string path;
	if( as.empty() )
	{
		path = mState.savePath();
	}
	if( path.empty() )
		path = QFileDialog::getOpenFileName( this, 
											"Load Project", 
											PathDatabase::userPath().c_str(), 
											QString("%1 (*.%2);;")
												.arg(mProjectFilterName.c_str())
												.arg(mProjectFilterExt.c_str()) 
												).toAscii().data();
	if( path.empty() ) return;
	
	Lit::RefPtr<Lit::SceneManager> mgr(Lit::Root::Instance().component<Lit::SceneManager>(Lit::COM_SCENEMANAGER));
	TiXmlDocument doc;
	doc.LinkEndChild( new TiXmlDeclaration( PROJECT_VERSION_STRING, "UTF-8", "yes" ) );
	TiXmlHandle projNode( new TiXmlElement("scene_project") );
	projNode.ToElement()->SetAttribute( "name", mName.c_str() );
	for( auto i=mItems.begin(); i!=mItems.end(); i++ )
	{
		ProjectItem * itm = i->second;
		std::string typ( trProjectItemType( itm->type ) );
		TiXmlHandle fileNode( new TiXmlElement("scene_node") );
		fileNode.ToElement()->SetAttribute( "name", itm->name.c_str() );
		fileNode.ToElement()->SetAttribute( "type", typ.c_str() );
		switch( itm->type )
		{
		case PIT_ENTITY:
			{
				Lit::EntityPtr ent = mgr->getEntity(itm->name);
				ent->exportAttribs(fileNode.ToElement());
			break;
			}
		case PIT_LIGHT:
			{
				Lit::LightPtr ent = mgr->getLight(itm->name);
				ent->exportAttribs(fileNode.ToElement());
			break;
			}
		case PIT_SOUND:
			break;
		};
		fileNode.ToElement()->SetAttribute( "name", itm->name.c_str() );
		projNode.ToElement()->LinkEndChild( fileNode.ToElement() );

	}
	doc.LinkEndChild( projNode.ToElement() );
	if( !doc.SaveFile( path.c_str() ) )
		throw Lit::IOError( path, doc.ErrorDesc(), EXC_LOC );

	mState.setSaved( true, path );
}
*/
class PathDatabase
{
public:
	static std::string appPath(){ return Lit::FileSystem::applicationPath(); }
	static std::string editorPath(){ return appPath() + "/editor"; }
	static std::string userPath(){ return editorPath() + "/user"; }
			
	static QString qtResources(){ return QT_RESOURCES_PATH; }
	static QString qtItemTypes(){ return QT_ITEM_TYPES_PATH; }
};

typedef Lit::RefPtr<ProjectStructure> ProjectStructurePtr;
typedef Lit::RefPtr<ProjectSaveState> ProjectSaveStatePtr;

class Project : public QTreeWidget, public Lit::MovableListener
{
	Q_OBJECT
public:

protected:
	typedef Lit::ResourcesListPtr		ResourcesListPtr;
	typedef ProjectSaveStatePtr			SaveStatePtr;
	typedef ProjectItemPreviewPtr		PreviewPtr;
	typedef ProjectItemPropertiesPtr	PropertiesPtr;
	typedef ProjectStructurePtr			StructurePtr;
	typedef ProjectStructure::NodePtr	NodePtr;

	ResourcesListPtr					mResources;
	std::string							mName;
	SaveStatePtr						mState;
	StructurePtr						mStructure;
	PreviewPtr							mPreview;
	PropertiesPtr						mProperties;

public:
	Project( QWidget * w, PreviewPtr preview, PropertiesPtr props, ResourcesListPtr res=NULL );
	Project( const std::string &proj_name, QWidget * w, PreviewPtr preview, PropertiesPtr props, ResourcesListPtr res=NULL );
	Project( const Project& rk );
	virtual ~Project();
		
	bool moveObject( Lit::Movable* mov, const Lit::Vec3 &position );
	bool scaleObject( Lit::Movable* mov, const Lit::Vec3 &scale );
	bool orientObject( Lit::Movable* mov, const Ogre::Quaternion &orientation );
	
	void mouseReleaseEvent( QMouseEvent * evt );
	SaveStatePtr state(){ return mState; }
	const SaveStatePtr state() const{ return mState; }
	
	void exportSceneAttribs( TiXmlElement * elem );

	void close();
	void save( );
	void open( );

	NodePtr findNode( Lit::MovablePtr mov );
	NodePtr findNode( const std::string &name );
	NodePtr findNode( ProjectNode::ItemPtr item );

	StructurePtr structure(){ return mStructure; }
	const StructurePtr structure() const{ return mStructure; }

	bool isModified( ) const{ mState->isModified(); }
	bool isSaved() const{ mState->isSaved(); }

	const ResourcesListPtr& resources() const;
	ResourcesListPtr resources();

	void destroyNode( NodePtr node );
	void create( const std::string &proj_name );
	void createByUserChoice( );

	NodePtr createMovable( const std::string &basename, ProjectNodeType type );

	QIcon itemTypeIcon( ProjectItemType type ) const;

protected slots:
	void previewMeshChangeRequest( QTreeWidgetItem * cur, QTreeWidgetItem * prev );
	void infosUpdateRequest( QTreeWidgetItem * item );

};
typedef Lit::RefPtr<Project> ProjectPtr;